/*
 * Copyright 2023-2024 Dozingfiretruck
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "nes.h"

/* https://www.nesdev.org/wiki/Mapper_30 */

static void nes_mapper_init(nes_t* nes){
    // 默认加载第一个PRG bank
    nes_load_prgrom_16k(nes, 0, 0);
    nes_load_prgrom_16k(nes, 1, nes->nes_rom.prg_rom_size - 1);

    nes_load_chrrom_8k(nes, 0, 0);
}

/* https://www.nesdev.org/wiki/Mapper_30 */
typedef struct {
    uint8_t P:5;    // PRG bank (5位支持32个16KB banks)
    uint8_t C:2;    // CHR bank (2位选择8KB banks)
    uint8_t M:1;    // 镜像模式控制
} bank_select_t;


// 在nes_mapper30.c中修改镜像控制逻辑
static void nes_mapper_write(nes_t* nes, uint16_t address, uint8_t data) {
    const bank_select_t* bank = (bank_select_t*)&data;

    // 根据ROM头信息判断镜像模式
    if (nes->nes_rom.four_screen) {
        // 强制四屏模式
        nes_ppu_screen_mirrors(nes, NES_MIRROR_FOUR_SCREEN);
    } else if (nes->nes_rom.mirroring_type == 1) {
        // 固定垂直镜像
        nes_ppu_screen_mirrors(nes, NES_MIRROR_VERTICAL); 
    } else {
        // Mapper动态控制模式
        switch(bank->M) {
        case 0:
            nes_ppu_screen_mirrors(nes, NES_MIRROR_ONE_SCREEN0);  // 单屏低地址
            break;
        case 1:
            nes_ppu_screen_mirrors(nes, NES_MIRROR_ONE_SCREEN1); // 单屏高地址
            break;
        }
    }
}

int nes_mapper30_init(nes_t* nes){
    // 设置默认镜像模式
     if (nes->nes_rom.four_screen) {
        nes_ppu_screen_mirrors(nes, NES_MIRROR_FOUR_SCREEN);
    } else {
        nes_ppu_screen_mirrors(nes, 
            (nes->nes_rom.mirroring_type == 1) ? 
            NES_MIRROR_VERTICAL : 
            NES_MIRROR_HORIZONTAL
        );
    }

    nes->nes_mapper.mapper_init = nes_mapper_init;
    nes->nes_mapper.mapper_write = nes_mapper_write;
    return 0;
}